// LedDisplay.cpp : implementation file
//

#include "stdafx.h"
#include "8085.h"
#include "LedDisplay.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLedDisplay dialog


CLedDisplay::CLedDisplay(CWnd* pParent /*=NULL*/)
	: CDialog(CLedDisplay::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLedDisplay)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
    m_pParent = pParent;
    Init();
}

CLedDisplay::~CLedDisplay()
{

}

void CLedDisplay::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLedDisplay)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CLedDisplay, CDialog)
	//{{AFX_MSG_MAP(CLedDisplay)
	ON_WM_PAINT()
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLedDisplay message handlers

void CLedDisplay::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
    CRect r;

    // draw a black rectangle
    GetClientRect(r);
    r.DeflateRect(10,10);
    CBrush b(RGB(0,0,0));
    dc.SelectObject(&b);
    dc.Rectangle(r);
	// TODO: Add your message handler code here
	POSITION pos=m_cLeds.GetHeadPosition();
    CLed *pLed;
	for(int i=0; pos ; )
	{
        pLed = m_cLeds.GetNext(pos);
        if(pLed->IsEmpty())
            continue;
        pLed->Draw(&dc,Get8085Object()->GetLedData(i));
        i++;
	}
	// Do not call CDialog::OnPaint() for painting messages
}

void CLedDisplay::Init()
{
    int i=0;
    // create the various LED's

    m_nXPos=25;
    m_nYPos=25;

	m_cLeds.RemoveAll();
    if(CMy8085App::IsIntelSDK())
	{
		// status field
		for(i=0; i<2 ; i++)
			Add(SEVEN_SEGMENT_LED);
		Add(EMPTY_LED);// add a empty LED

		// data field
		for(i=0; i<4 ; i++)
			Add(SEVEN_SEGMENT_LED);
		Add(EMPTY_LED);// add a empty LED

		// address field
		for(i=0; i<2 ; i++)
			Add(SEVEN_SEGMENT_LED);
		Add(EMPTY_LED);// add a empty LED
	}
}

void CLedDisplay::PostNcDestroy() 
{
	// TODO: Add your specialized code here and/or call the base class
    POSITION pos;
    CLed *pLed;
    for(pos = m_cLeds.GetHeadPosition() ; pos ; )
    {
        pLed = m_cLeds.GetAt(pos);
        delete pLed;
        m_cLeds.GetNext(pos);
        m_cLeds.RemoveHead();
    }
    //for(int i=0; i<NUM_OF_LEDS ; i++)
    //    delete m_cLeds[i];

    delete this;
	//CDialog::PostNcDestroy();
}

void CLedDisplay::Refresh(BOOL bForce)
{
	if(Get8085Object()->IsLedDataModified() || bForce)
	{
		InvalidateRect(NULL);
		Get8085Object()->SetLedDataModified(FALSE);
	}
}

// Add an LED to the m_cLed, if nType=0(default) then add
// a seven segment LED, if it is '1' add a CLedSpace
// An LED added cannot be removed
void CLedDisplay::Add(int nType)
{
    int nWidth=0;
	CLed *pLed;

	// add to end of list
	if(nType==SEVEN_SEGMENT_LED)
		pLed = new CSevenSegment;
	else 
		pLed = new CLedEmpty;

	m_cLeds.AddTail(pLed);
	pLed->Create(m_nXPos,m_nYPos);
    nWidth = pLed->GetWidth();
    m_nXPos += 3*nWidth;
}

void CLedDisplay::OnClose() 
{
	// TODO: Add your message handler code here and/or call default

    // send this message to the C8085Display class so that
    // it can toggle the ID_BUTTON_SHOW_LED of the debug toolbar
    CWnd *p = GetParent();
    if(IsWindow(m_pParent->m_hWnd))
        m_pParent->PostMessage(ID_LED_DISPLAY_CLOSED,0,0);
	CDialog::OnClose();
}

void CLedDisplay::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
}
